<template>
  <div class = "login_container">
    <div class = "login_box">
      <div class = "avatar_box">
        <img src = "../assets/img/logo.png" alt = "">
      </div>
      <div class = "login_form">
        <!-- ！！通过vue中的element-ui提交表单的方式记住！！ -->
        <!--
            1. 先给el-form动态绑定model属性值为一个data里面的一个对象，比如这里的:model=form
               这个model属性是由element-ui提供的，el-form是一个组件，所以这里动态绑定的model也就是传递参数，
               model的主要作用就是存储表单中的所有数据对象
        -->
        <!--
            a. 对于element-ui表单中可以使用动态绑定rules属性，绑定验证规则，可以在对数据进行一次基础性的验证后发送。
            同样的需要在data中定义验证规则
         -->
        <!--1) 重置按钮的功能完成，el-form表单中自带resetFields方法可以重置所有表单，第一步是添加ref
            ref是vue中自带的属性，可以通过这个属性为子组件添加引用 例如这里添加 ref=loginFormRef
            我们就可以通过 this.$ref.loginFormRef来访问这个子组件和使用子组件的属性和方法
        -->
        <!--
            i. 登录前的预验证，对于表单来说，在按下提交按钮后不应该直接向服务器发送请求，而是对信息再进行一次校验，校验
               完成后再发送请求
         -->
        <el-form :model = "form" :rules = "rules" label-width = "65px" ref = "loginFormRef">
          <!-- b.要进行数据验证，要对el-form-item标签添加prop属性，并且传入对应的规则的名字 例如 -->
          <el-form-item label = "用户名" prop = "username">
            <!-- 2. 使用双向绑定代替name属性(name原生属性也可以），双向绑定的值应该是给el-form动态绑定的对象的属性，比如这里的值为form.user -->
            <el-input
              placeholder = "请输入用户名"
              prefix-icon = "el-icon-s-custom"
              v-model = "form.username"></el-input>
          </el-form-item>
          <!-- 进行数据验证添加prop属性 -->
          <el-form-item label = "密码" prop = "password">
            <!-- 使用双向绑定代替name属性 -->
            <!--
                element-ui中没有明确定义的密码框，但是可以使用type属性来说明 type="password" 时表示密码框，
                还可以使用show-password属性来得到一个可以切换显示隐藏的密码框
            -->
            <!--            <el-input-->
            <!--              placeholder = "应输入密码"-->
            <!--              prefix-icon = "iconfont icon-xianxingshirun"-->
            <!--              v-model = "form.password"-->
            <!--              type = "password"></el-input>-->
            <!-- 使用show-password属性得到切换显示隐藏的密码框 -->
            <el-input
              placeholder = "应输入密码"
              prefix-icon = "iconfont icon-xianxingshirun"
              v-model = "form.password"
              show-password></el-input>
          </el-form-item>
          <el-form-item class = "btns">
            <!--ii. 在按下确认键后，还需要对表单数据再进行一次校验。在这里添加点击函数 具体操作看下面的点击函数-->
            <el-button type = "primary" @click = "validataClick">确认</el-button>
            <!-- 2)为重置按钮添加点击函数，点击函数就可以直接调用el-form中的resetFields函数 -->
            <!--
            vue中的实例在html中不需要使用this 在script中需要使用this  比如这里直接使用 $refs
            就不必在script中使用this.$refs.loginFromRef.resetFields()
             -->
            <el-button type = "info" @click = "$refs.loginFormRef.resetFields()">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Login',
  data () {
    return {
      // 这里登录表单的数据绑定对象
      form: {},
      // 这里时表单的验证规则
      rules: {
        // 这里是针对不同的输入框有不同的规则
        /*
          * 规则的属性：
          * 1. required 值为布尔值，值为true表示该空必需, 当添加了该属性时会自动加上红色的星形符号
          *    el-form-item如果不需要校验但是必需的话也可以直接在标签中添加该属性
          *    例如：<el-form-item label = "密码" required>
          * 2. message：错误时的提示信息
          * 3. trigger：暂时只知道两个值:change,blur。   trigger是触发的意思，blur是模糊也就是失去焦点时触发
          * 4. min：最小长度
          * 5. max：最大长度
          * 6. type：指定数据类型
          * */
        username: [
          // 用户名的验证规则，一个对象就是一个验证规则，其中包括了验证目的，验证信息，验证触发条件
          { required: true, message: '请输入用户名', trigger: 'blur' },
          { min: 4, max: 12, message: '长度在4-10之间', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { min: 6, max: 12, message: '长度在4-10之间', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    validataClick () {
      // validata方法是el-form表单自带的一种方法， 参数是一个回调函数，
      // 如果没有传入回调函数的话，会返回一个promise
      this.$refs.loginFormRef.validate((valid, a) => {
        // 该回调函数会传入两个参数:是否校验成功和未通过校验的字段
        // 所以这里的valid是是否通过校验，a是没有通过校验的字段，valid是布尔值，a是一个对象
        // 校验的规则其实也就是上面自定义的校验规则
        // console.log(valid, a)
        if (!valid) return // 判断是否通过校验，如果通过校验就发起请求，没有通过校验就返回

        // 发起请求要使用axios模块，这个模块也需要在全局引用，这个模块不需要Vue.use()
        // 所以也可以得知在el-form并没有默认的提交事件，而是通过点击事件自己发出请求  使用axios发出请求（已经注册全局$http)
        this.$http.post('/login', this.form).then(ret => {
          /*
            * 消息提示功能实现： 当我们点击登录时应该有对应的消息提示， 这个功能在element-ui上也有实现，需要在element-ui
            * 中导入Message，并且使用一个参数全局挂载,比如 Vue.prototype.$message=Message
            * 这是一个方法，调用该方法并传递参数就可以进行弹窗消息通知。
            * */
          console.log(ret.data)
          // 可以像这样传入一个对象，有message属性和type属性使用，type属性主要有 ：success，warning，error 三种
          if (ret.data.meta.status !== 200) {
            this.$message({
              message: ret.data.meta.msg + '，请重试',
              type: 'error'
            })
          }
          // 也可以像这样直接在不传入type的方式中使用
          else this.$message.success('登录成功')
          // 或者是最平常的在$message 中直接传入字符串  具体的操作见element-ui官网
          // this.$message('最平常的使用方式')

          // 登录完成后，我们需要对用户的token进行保存， 这里的token是由服务器随机生成的，每次的值都不一样
          // 我们需要保存来确定用户的真实性  sessionStorage 只在网站打开期间生效，退出网站就会被删除,刷新网页不会被删除
          // 一般使用setItem保存数据 getItem获取数据 removeItem删除保存的数据 clear删除所有数据
          window.sessionStorage.setItem('token', ret.data.data.token)

          // 存储token到sessionStorage后就要跳转页面了  通过this.$router.push()跳转
          this.$router.push('/home')
        })
      })
    }
  }
}
</script>

<style lang = "less" scoped>
  .login_container {
    background-color: #2b4b6b;
    height: 100%;
    position: relative;
  }

  .login_box {
    width: 450px;
    height: 350px;
    background-color: #fff;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border-radius: 5px;
  }

  .avatar_box {
    height: 130px;
    width: 130px;
    border-radius: 50%;
    padding: 10px;
    box-shadow: 0 0 10px #999999;
    position: absolute;
    left: 50%;
    transform: translate(-50%, -30%);

    img {
      width: 100%;
      height: 100%;
      border-radius: 50%;
      background-color: #eee;
    }
  }

  .login_form {
    width: 400px;
    height: 200px;
    position: absolute;
    top: 40%;
    left: 50%;
    transform: translate(-50%);
  }

  .btns {
    display: flex;
    justify-content: flex-end;
  }
</style>
